import moment from 'moment'
import business from 'moment-business';
import {getCalendar} from '@/api/calc/otcOption/calc'
import {getDailyPrice} from '@/api/calc/otcOption/calc'
import {listData} from "@/api/system/dict/data"
import {components} from "./data";
import calendar from "../../../../../store/modules/calendar";
import { isVoid,calcAnnualizedByTerminationPaymentDate} from '@/utils/util'
import { createStore } from 'vuex'
import {ElNotification,ElMessage } from "element-plus";
import {getCurrentInstance} from 'vue';
const proxy = getCurrentInstance();
const getters = {
  /*交易日历*/
  calendars:state => state.calendar
}

const store = createStore({
  modules: {
    calendar
  },
  getters
});

// 获取日历数据，并加载到vuex 的store中
store.dispatch("GetCalendars");
// 获取日历数据，并加载到vuex 的store中

//是否为交易日
export function isTradeDates(date) {
  return store.getters.calendars.tcalendarDates.includes(date)
}
export function getInstrument(optionType) {
  if (isVoid(optionType)) return 
  let component = components[String(optionType).toLowerCase()]
  if (isVoid(component)){
    ElMessage.warning("暂未支持此品种" + optionType)
    // ElNotification.warning("暂未支持此品种" + optionType)
    return false
  }
  return component
}
/*
*
* 获取支持的期权类型列表
*
* */
export async  function getOptionList() {
  return new Promise(resolve => {
    listData({
      pageNum: 1,
      pageSize: 25,
      dictName: undefined,
      dictType: 'optionType',
      status: 0
    }).then((res) => {
      resolve(res.rows.map(item => {
        return {
          value: item.dictValue,
          label: item.dictLabel
        }
      }))
    })
  })

}
/**
 * 根据频率，获取一段时间的具体日期
 * @param startDate 时间段的开始日期
 * @param endDate 时间段的结束日期
 * @param frequency 频率 数字+单位，如：1y，2m，3w，4d，单位不区分大小写
 * @param isIncludeBorder 是否包含边界，开始和结束日期是否包含，默认不包含
 */
export async function getFrequencyDatesInTcalendarDates(startDate, endDate, frequency, isIncludeBorder) {

  return new Promise(resolve => {
    getCalendar({}).then((res)=>{
      if (res.errorCode<0) return
      var frequencyDatesInTcalendarDates = res.result.map(item=> item.CAL_DAY);
      let lastDate = res.result.map(item=> item.CAL_DAY)[res.result.map(item=> item.CAL_DAY).length-1]
      /*若存在系统交易日历不能覆盖到实际交易日区间，则从不能覆盖的日期开始，默认工作日为交易日*/
      if (endDate > lastDate){
        let workDates = generateWordDates(lastDate)
        frequencyDatesInTcalendarDates = [...frequencyDatesInTcalendarDates,...workDates]
      }
      if (!startDate || !endDate || !frequency) {
        return [];
      }
      isIncludeBorder = isIncludeBorder ? true : false;
      var unit = frequency.substr(-1);
      var number = frequency.replace(unit, '');
      var date = getDateAdd(startDate, "1", unit);
      var dates = [];
      
      while (date <= endDate&&date<="2050-12-12") {
        let temp = date;
        if ((date == startDate && isIncludeBorder) ||
            (date > startDate && date < endDate) ||
            (date == endDate && isIncludeBorder)
        ) {

          while (frequencyDatesInTcalendarDates.indexOf(temp) == -1) {
            temp = getDateAdd(temp, "1", "D");
          }
          dates.push(temp);
          // date = temp;
        }
        date = getDateAdd(date, number, unit);
      }
      resolve(dates)
    })
  })
}

 /**
 *   功能:实现VBScript的DateAdd功能.
 *   参数:interval,字符串表达式，表示要添加的时间间隔.
 *   参数:number,数值表达式，表示要添加的时间间隔的个数.
 *   参数:date,时间对象.
 *   返回:新的时间对象.
 *   var   now   =   new   Date();
 *   var   newDate   =   DateAdd( "d ",5,now);
 *---------------   DateAdd(interval,number,date)   -----------------
 */
export function getDateAdd(date, number, interval) {
  date = new Date(date);
  number = Number(number);
  switch (interval) {
    case "y":
    case   "Y"   : {
      date.setFullYear(date.getFullYear() + number);
      break;
    }
    case "q":
    case   "Q"   : {
      let newMouthIndex = date.getMonth() + number * 3;
      if (newMouthIndex%11==2&&date.getDate()>=28){
        date.setMonth(2,0);
      }else {
        date.setMonth(date.getMonth() + number * 3);
      }
      break;
    }
    case "m":
    case   "M"   : {
      if (date.getMonth()==0&&date.getDate()>=28){
        date.setMonth(2,0);
      }else {
        date.setMonth(date.getMonth() + number);
      }
      break;
    }
    case "w":
    case   "W"   : {
      date.setDate(date.getDate() + number * 7);
      break;
    }
    case "d":
    case   "D"   : {
      date.setDate(date.getDate() + number);
      break;
    }
    default   : {
      date.setDate(d.getDate() + number);
      break;
    }
  }
    return    moment(date).format('YYYY-MM-DD')
 }

/** 查询价格类型类型列表 */
export  async function getDailysPrice(query) {
  let instrumentId = query.instrumentId
  if (!instrumentId) return
  let strings = instrumentId.split(',')

  var param = {
    iCode: strings[0],
    aType: strings[1],
    mType: strings[2],
    begDate: query.valueDate
  }

  return await getDailyPrice(param).then(response => {
    /*
    * "dpOpen"
      "dpClose"
      "dpHigh"
      "dpLow"
      "dpAvg"
    * */
    // return this.lsh.ceil(response.result.dpClose,4);
    /*
  dpClose    1
  dpSet      2
  dpAvg      3
  价格类型可选list  【0,1，2】
 * */
    let result = response.result
    if (response.result == null) {
      return false
    }
    let filterList = []
    if (!Boolean(result)) return {result: {dpClose: 0}}
    if (Boolean((result.dpAvg))) filterList.push(3)
    if (Boolean((result.dpSet))) filterList.push(2)
    if (Boolean(result.dpClose)) filterList.push(1)
    if (Boolean(result.dpRelTime)) filterList.push(0)
    result.filterList = filterList.toString()
    return result
  })
}

//生成观察序列
export async function generateOberserDates(form) {
  return getFrequencyDatesInTcalendarDates(form.data.effectiveDate, form.data.terminationDate, form.data.ObserFrequency, Boolean(form.data.isIncludeStartDate.length))
      .then((dates) => {
        form.knocks.length = 0
        dates.forEach(item => {
          let itemDate = {
            'trigger': {
              'type': form.data.knockType == '' ? 'EqualOrLess' : 'EqualOrGreater',
              // 'level': form.data.strike,
              'levelPercentage': Number(form.data.konckLevelPercentage / 100).toFixed(4)
            },
            'observeDate': {
              'endDate': item,
              'endDateConv': 'FOLLOWING',
              'calendar': 'CHINA_EX'
            },
            'calclationPeriod': {
              'startDate': form.data.effectiveDate,
              'startDateConv': 'FOLLOWING',
              'isIncludeStartDate': form.data.isIncludeStartDate,
              'endDate': item,
              'endDateConv': 'FOLLOWING',
              'calendar': 'CHINA_EX',
              'isIncludeEndDate': form.data.isIncludeEndDate
            },
            'basicYield': {
              'paymentAmount': '',
              'paymentAmountPecentage': Number(form.data.knockOutYield / 100).toFixed(4),
              'daycounter': form.data.knockOutYieldYear == '1' ? form.data.daycounter : '',
              'participationRate': '1.0'
            },
            'minimumYields': [
              {
                'paymentAmount': '',
                'paymentAmountPecentage': Number(form.data.MarginYield / 100).toFixed(4),
                'daycounter': form.data.MarginYieldYear == '1' ? form.data.daycounter : '',
                'participationRate': '1.0'
              }
            ],
            'paymentDate': item,
            'paymentDateOffset': '',
            'paymentDateConv': 'FOLLOWING',
            'paymentDateCalendar': 'CHINA_EX'
          }
          form.knocks.push(itemDate)
        })
        return form.knocks
      })
}

function generateWordDates(startDate) {
  let dates = [];
  let item = moment(startDate)
  while (item<moment('2050-12-30')){
    item = business.addWeekDays(item,1)
    dates.push(item.format('YYYY-MM-DD'))
  }

  return dates
}


/*设置标的价格逻辑*/

export function setCommonSpotPrice(proxy,form,props){
  if (form.initFlag) {
    return
  }
    proxy.$refs.PricingParamRef.setSpotPrice({
    valueDate:props.valueDate,
    instrumentId:form.data.instrumentId
  })
  if (form.data.instrumentId != null &&form.data.effectiveDate != null && props.useType != 'show') {
    proxy.$refs['underlyerIdRef'].getDailyPrice({
      instrumentId: form.data.instrumentId,
      startDate: moment(props.valueDate).isBefore(form.data.effectiveDate)? props.valueDate: form.data.effectiveDate
    }).then((price) => {
      if (price) {
        if (form.data.priceOnWait == '1') {
          return
        }
        //  若价格为0 则过滤对应的价格类型
        form.data.spotPrice = price.dpClose
      }
    })
  }
}
/*计算npv*/
export function CalcNpvByNpvPercent(form,percent,hasAnnualized) {
  if (hasAnnualized){
    //根据NpvYearPercent算出npv
    // "yearnpvPercentage": 100 * result.contract.npv / data.instrument.termsheet.notional /(term/ 365),
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    return form.data.notional * percent / 100 * annualized
  }else {
    // "npvPercentage": 100 * result.contract.npv / data.instrument.termsheet.notional,
    // 根据NpvPercent算出npv
    return form.data.notional * percent / 100
  }
}


/*计算NpvPercent*/
export function CalcNpvPercentByNpv(form,npv,hasAnnualized) {
  if (!hasAnnualized){
    //根据NpvYearPercent算出npv
    // "yearnpvPercentage": 100 * result.contract.npv / data.instrument.termsheet.notional /(term/ 365),
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    return (100 * npv / form.data.notional )/ annualized
  }else {
    // "npvPercentage": 100 * result.contract.npv / data.instrument.termsheet.notional,
    // 根据NpvPercent算出npv
    return 100 * npv / form.data.notional
  }
}
